package com.radiation.rms.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.radiation.rms.common.R;
import com.radiation.rms.common.RMSCommon;
import com.radiation.rms.common.RMSConstant;
import com.radiation.rms.entity.AbnormalData;
import com.radiation.rms.entity.Area;
import com.radiation.rms.entity.Device;
import com.radiation.rms.entity.RealTimeData;
import com.radiation.rms.mapper.RealTimeDataMapper;
import com.radiation.rms.service.AbnormalDataService;
import com.radiation.rms.service.AreaService;
import com.radiation.rms.service.DeviceService;
import com.radiation.rms.service.RealTimeDataService;
import com.radiation.rms.vo.RealDataVo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 实时数据表 服务实现类
 * </p>
 *
 * @author 1062
 * @since 2021-04-02
 */
@Service
public class RealTimeDataServiceImpl extends ServiceImpl<RealTimeDataMapper, RealTimeData> implements RealTimeDataService {
    @Autowired
    private AreaService areaService;
    @Autowired
    private AbnormalDataService abnormalDataService;
    @Autowired
    private RMSCommon rmsCommon;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public R getRealTime(RealDataVo realDataVo) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        List<String> departmentIds = rmsCommon.getDepartmentIds(username);
        if (departmentIds == null || departmentIds.size() == 0) {
            return R.error().message(RMSConstant.PERMISSION_DENIED);
        }
//        realDataVo.setDepartmentIds(departmentIds);
        List<Device> macs = deviceService.getMac(departmentIds);
        BoundHashOperations<String, String, String> ops = redisTemplate.boundHashOps("device:info");
        Iterator<Device> iterator = macs.iterator();
        Set<String> keys = ops.keys();
        while (iterator.hasNext()) {
            Device next = iterator.next();
            if (!keys.contains(next.getMac())) {
                iterator.remove();
            }
        }
        List<List<Device>> partition = ListUtils.partition(macs, Math.min(macs.size(), 10));
        List<Device> devices = partition.get(realDataVo.getCurrentPage() - 1);
        if (CollectionUtils.isEmpty(devices)) {
            return R.error("分页错误");
        }
        List<RealTimeData> collect = devices.stream().map(device -> {
            String s = ops.get(device.getMac());
            RealTimeData realTimeData = JSON.parseObject(s, RealTimeData.class);
            Area byId = areaService.getById(device.getDepartmentId());
            realTimeData.setDepartmentName(byId.getName());
            realTimeData.setDepartmentId(device.getDepartmentId());
            realTimeData.setFullName(areaService.getPath(device.getDepartmentId()));
            return realTimeData;
        }).collect(Collectors.toList());
//        List<RealTimeData> realTimeDatas = this.baseMapper.getRealTime(realDataVo);
        return R.ok().data("items", collect).data("total", macs.size());
    }

    @Override
    public R showChart(RealDataVo realDataVo) {
        Integer num = realDataVo.getNum();
        if (num >= 200) {
            return R.error("当前系统仅查看最近200条记录");
        }
        List<RealTimeData> realTimeDataList = this.baseMapper.showChart(realDataVo);
        List<String> params = new ArrayList<>();
        List<Double> data = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
        Date previous = null;
        String dateStr = "";
        int count = 0;
        for (RealTimeData realTimeData : realTimeDataList) {
            Date gmtCreate = realTimeData.getGmtCreate();
            if (count == 0) {
                dateStr = dateFormat.format(gmtCreate);
            } else {
                if (determineDate(previous, gmtCreate)) {
                    // 同一天
                    dateStr = timeFormat.format(gmtCreate);
                } else {
                    dateStr = dateFormat.format(gmtCreate);
                }
            }
            count++;
            previous = gmtCreate;
            params.add(dateStr);
            data.add(realTimeData.getRecord());
        }
        return R.ok().data("params", params).data("data", data);
    }

    private boolean determineDate(Date previous, Date gmtCreate) {
        Calendar calPrevious = Calendar.getInstance();
        Calendar calDate = Calendar.getInstance();
        calPrevious.setTime(previous);
        calDate.setTime(gmtCreate);
        return calPrevious.get(Calendar.YEAR) == calDate.get(Calendar.YEAR) &&
                calPrevious.get(Calendar.DAY_OF_YEAR) == calDate.get(Calendar.DAY_OF_YEAR);
    }

    @Override
    @Transactional
    public R saveReal(RealTimeData realTimeData) {
        List<RealTimeData> realTimeDatas = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            RealTimeData real = new RealTimeData();
            real.setMac("2222");
            real.setRecord(Math.random());
            real.setStatus("1");
            realTimeDatas.add(real);
        }
        List<AbnormalData> abnormalDataList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            RealTimeData real = new RealTimeData();
            real.setMac("2222");
            real.setRecord(Math.random());
            real.setStatus("0");
            realTimeDatas.add(real);
            AbnormalData abnormalData = new AbnormalData();
            abnormalData.setMac("2222");
            abnormalData.setRecord(Math.random() + 1);
            abnormalDataList.add(abnormalData);
        }
        saveBatch(realTimeDatas);
        abnormalDataService.saveBatch(abnormalDataList);
        return R.ok();
    }
}
